﻿using System.Collections.Generic;
using System.Linq;
using Red.Controls.Diagrams.Declarators;
using Red.Controls.Diagrams.ViewModels;

namespace Red.Controls.Diagrams
{
    abstract class BaseObjectManager
    {
        #region Data

        protected readonly NodeDeclarators _declarators;
        protected readonly DiagramViewModel _viewModel;

        #endregion Data

        #region Protected methods

        protected BaseObjectManager( NodeDeclarators declarators, DiagramViewModel viewModel )
        {
            _declarators = declarators;
            _viewModel = viewModel;
        }

        protected NodeViewModel CreateNodeViewModel( IObject nodeObject )
        {
            var nodeClass = nodeObject.Class;
            var declarator = GetNodeDeclarator( nodeClass );
            var nodeViewModel = NodeViewModelFactory.CreateNodeViewModel( _declarators, declarator, nodeObject );
            return nodeViewModel;
        }

        protected NodeDeclarator GetNodeDeclarator( string className )
        {
            var declarator = _declarators.GetNodeDeclarator( className );
            // declarator is missing for given class name
            if ( declarator == null )
            {
                declarator = _declarators.GetNodeDeclarator( InternalClassNames.MissingDeclarator );
                declarator.Title = "Missing declarator: " + className;
            }
            return declarator;
        }

        protected IEnumerable<ConnectionViewModel> CreateConnections( List<NodeViewModel> nodeViewModels )
        {
            var connectionViewModels = new List<ConnectionViewModel>();
            var outputConnectorsWithValue =
                nodeViewModels.SelectMany( item => item.OutputConnectors )
                    .Where( item => item.Property != null && item.Property.Values.Any() );

            foreach ( var output in outputConnectorsWithValue )
            {
                var propertyData = output.Property.Values;
                foreach ( var value in propertyData.Values )
                {
                    if ( string.IsNullOrEmpty( value ) )
                        continue;

                    var targetNode = nodeViewModels.FirstOrDefault( item => item.ID == value );
                    if ( !targetNode.InputConnectors.Any() )
                    {
                        // TODO: node should have connector, we should fix declarator file, this should be reported somehow
                        continue;
                    }
                    var destConnector = targetNode.InputConnectors.First();
                    var connectionViewModel = new ConnectionViewModel
                    {
                        SourceConnector = output,
                        DestConnector = destConnector
                    };
                    connectionViewModels.Add( connectionViewModel );
                }
            }

            return connectionViewModels;
        }

        #endregion Protected methods
    }
}
